import './style.less';
import { FC, useEffect, useState } from 'react';

import classNames from 'classnames';

import { onFieldChange } from '@formily/core';

import { DownOutlined, UpOutlined } from '@ant-design/icons';
import { useForm } from '@formily/react';
import { toArray } from '@/biz-components/_common/util';

// @ts-ignore
import template from 'es6-template-strings';
import { plus, minus, times, divide, round } from '@/biz-components/_common/numberPrecision';

interface DataItem {
  label: string;
  value: string;
  expression?: string;
}

interface FormTagProps {
  dataSource?: DataItem[];
  dependencies?: string[];
}

const FormTag: FC<FormTagProps> = ({ dependencies, dataSource, height }) => {
  const [open, setOpen] = useState(true);

  const [value, setValue] = useState<DataItem[]>([]);

  const form = useForm();

  const [diffTop, setDiffTop] = useState('50px');

  const handleClick = () => {
    setOpen(!open);
  };

  useEffect(() => {
    if (form) {
      const formId = form.id;

      const dom = document.querySelector(`.form-id-${formId}`);

      if (dom) {
        const { top } = dom.getBoundingClientRect();

        setDiffTop(`${top + 5}px`);
      }
    }
  }, [form]);

  const compile = (expression: string) => {
    return new Function(
      '$deps',
      'plus',
      'minus',
      'times',
      'divide',
      'round',
      `return ${expression}`,
    );
  };

  const compute = () => {
    if (Array.isArray(dependencies) && Array.isArray(dataSource)) {
      const $deps: any = [];

      dependencies.forEach((key) => {
        $deps.push(form.getValuesIn(key));
      });

      setValue(
        dataSource.map((item) => {
          const { expression } = item;
          return {
            ...item,
            value: expression ? compile(expression)($deps, plus, minus, times, divide, round) : 0,
          };
        }),
      );
    }
  };

  useEffect(() => {
    if (Array.isArray(dependencies)) {
      form.addEffects('depsChange', () => {
        dependencies.forEach((key) => {
          onFieldChange(key, ['value'], () => {
            compute();
          });
        });
      });
    }

    if (Array.isArray(dataSource)) {
      setValue(dataSource);
    }

    return () => {
      form.removeEffects('depsChange');
    };
  }, [form, dependencies, dataSource]);

  return (
    <div
      className="form-tag"
      onClick={handleClick}
      style={{
        top: diffTop,
      }}
    >
      <div className="pony-roll">
        <div
          className={classNames('ribbon', {
            'ribbon-active': open,
          })}
        >
          {open ? <UpOutlined /> : <DownOutlined />}

          <div className="ribbon2">
            {open ? (
              <div>
                {toArray(value).map((item) => {
                  const { label, value } = item || {};
                  return (
                    <div key={label}>
                      {label}: {value}
                    </div>
                  );
                })}
              </div>
            ) : null}
          </div>
        </div>
      </div>
    </div>
  );
};

export default FormTag;
